package net.xuele.learn.rsocket.support;

import io.rsocket.Payload;
import io.rsocket.util.DefaultPayload;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author: patrick-Hikari
 * @description:
 * @date: 2021/8/18 6:33 下午
 */
@Slf4j
public class GameController implements Publisher<Payload> {

    private final String playerName;
    private final List<Long> shots;
    private Subscriber<? super Payload> subscriber;

    private boolean truce = false;

    public GameController(String playerName) {
        this.playerName = playerName;
        this.shots = generateShotList();
    }

    /**
     * Create a random list of time intervals, 0-1000ms
     * @return
     */
    private List<Long> generateShotList() {
        return Flux.range(1, 10)
                .map(e -> (long) Math.ceil(Math.random() * 1000))
                .collectList()
                .block();
    }


    @Override
    public void subscribe(Subscriber<? super Payload> subscriber) {
        this.subscriber = subscriber;
        fireWill();
    }

    /**
     * 异步的发布游戏事件
     */
    private void fireWill() {
        CompletableFuture.runAsync(()->{
            for (Long shot : shots) {
                try {
                    Thread.sleep(shot);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (truce) {
                    break;
                }
                System.out.println("bang! === " + playerName);
                subscriber.onNext(DefaultPayload.create("bang!"));
            }
            if (!truce) {
                System.out.println("i give up " + playerName);
                subscriber.onNext(DefaultPayload.create("i give up"));
            }
            subscriber.onComplete();
        });
    }

    /**
     * 处理来自对手的事件
     * @param payload
     */
    public void processPayload(Payload payload) {
        String message = payload.getDataUtf8();
        switch (message) {
            case "bang!":
                String result = Math.random() < 0.5 ? "Haha missed!" : "Ow!";
                log.info("{}: {}", playerName, result);
                break;
            case "I give up":
                truce = true;
                log.info("{}: OK, truce", playerName);
                break;
        }
    }
}
